package com.ruoyi.srmcontract.service.impl;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ruoyi.srmcontract.domain.JacContract;
import com.ruoyi.srmcontract.domain.JacContractItem;
import com.ruoyi.srmcontract.domain.JacContractItemImp;
import com.ruoyi.srmcontract.domain.JacContractPrice;
import com.ruoyi.srmcontract.domain.JacContractPriceList;
import com.ruoyi.srmcontract.mapper.JacContractItemMapper;
import com.ruoyi.srmcontract.mapper.JacContractMapper;
import com.ruoyi.srmcontract.service.IJacContractItemService;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.google.common.base.Joiner;
import com.ruoyi.common.constant.Constants;

import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;



/**
 * 合同物料明细Service业务层处理
 * 
 * @author ygx
 * @date 2020-08-06
 */
@Service
public class JacContractItemServiceImpl implements IJacContractItemService 
{   
	private static final Logger log = LoggerFactory.getLogger(JacContractItemServiceImpl.class);
    @Autowired
    private JacContractItemMapper jacContractItemMapper;
    @Autowired
    private JacContractMapper jacContractMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private JacContractPriceMain jacContractPriceMain;
    
    private static final String END = "end";


    /**
     * 查询合同物料明细
     * 
     * @param companycode 合同物料明细ID
     * @return 合同物料明细
     */
    @Override
    public JacContractItem selectJacContractItemById(String companycode)
    {   
        return jacContractItemMapper.selectJacContractItemById(companycode);
    }

    /**
     * 查询合同物料明细列表
     * 
     * @param jacContractItem 合同物料明细
     * @return 合同物料明细
     */
    @Override
    public List<JacContractItem> selectJacContractItemList(JacContractItem jacContractItem)
    {
        return jacContractItemMapper.selectJacContractItemList(jacContractItem);
    }
    
    /**
     * 查询需要导出到Excel的合同物料明细列表
     * 
     * @param jacContractItem 合同物料明细
     * @return 合同物料明细集合
     */
    public List<JacContractItem> selectExcelList(JacContractItem jacContractItem)
    {
    	return jacContractItemMapper.selectExcelList(jacContractItem);
    }

    /**
     * 新增合同物料明细
     * 
     * @param jacContractItem 合同物料明细
     * @return 结果
     */
    @Override
    public int insertJacContractItem(JacContractItem jacContractItem)
    {   
        return jacContractItemMapper.insertJacContractItem(jacContractItem);
    }
    
    
    /**
     * 新增合同物料明细(Excel导入)
     * 
     * @param jacContractItem 合同物料明细
     * @return 结果
     */
    @Override
    public String excelInsertItem(JacContractItemImp jacContractItemImp,int rowid)
    {   
    	String result = "1";
    	String contractcode =jacContractItemImp.getContractcode();
    	if (!"ContractNew".equals(jacContractMapper.checkStatus(contractcode)))
    	{
    		return "只允许新增状态合同新增物料！";
    	}
    	//获取当前时间和当前用户名
    	Long date = Long.valueOf(new SimpleDateFormat("yyyyMMdd").format(new Date()));
    	String time = new SimpleDateFormat("HHmmss").format(new Date());
    	HttpServletRequest request = ServletUtils.getRequest();
        String user = request.getHeader(Constants.CURRENT_USERNAME);
        String username = jacContractMapper.selectUserNameById(request.getHeader(Constants.CURRENT_ID));
        //判断税率是否为空
		if (jacContractItemImp.getRate() == null)
		{
			jacContractItemImp.setRate(13.0);
		}
        
    	String itemcodeImp = jacContractItemImp.getItemcode();
	  	if (itemcodeImp == null || StringUtils.isBlank(itemcodeImp))
			{   
			    result = "导入模板第" + rowid + "行" +"物料代码为空，不允许导入";
				log.info(result);
				return result;
			}
    	//替换字符串左右两端的空格。并且将文件中 &nbsp（char ASCII code 160）;， 回车，换行符 替换;字符串中间连续的空格替换成一个的方法：
    	String itemcode = itemcodeImp.replace(String.valueOf((char)160), "").trim().replaceAll("[\\r|\\n]+", "").replaceAll("\\s+", " ");
  
    	if (jacContractItemImp.getUntaxprice() == null)
		{   
		    result = "导入模板第" + rowid + "行，物料代码" + itemcode +"的未税价格为空，不允许导入";
			log.info(result);
			return result;
		}
    	if (jacContractItemImp.getQuantity() == null)
		{   
		    result = "导入模板第" + rowid + "行，物料代码" + itemcode +"的订货量为空，不允许导入";
			log.info(result);
			return result;
		}
    	if (jacContractItemMapper.checkitem(jacContractItemImp.getItemcode(),jacContractItemImp.getContractcode()) > 0)
    		{   
    		    result = "导入模板第" + rowid + "行，物料代码" + itemcode + "在改合同已存在，不允许导入";
    			log.info(result);
    			return result;
    		}
       	String itemname = jacContractItemMapper.selectItemName(itemcode);
        if (StringUtils.isBlank(itemname) || "".equals(itemname))
            {   
        	    result = "导入模板第" + rowid + "行，物料代码" + itemcode + "，系统中无此物料，不允许导入";
        	    log.info(result);
            	return result;
            }
    		else 
    		 {  
        		//获取含税单价
        		Double price = getPrice(jacContractItemImp.getUntaxprice(),jacContractItemImp.getRate());
        		jacContractItemImp.setPrice(price);
        		//获取含税金额
        		jacContractItemImp.setTotalamount(getTotalamount(price,jacContractItemImp.getQuantity()));
        		//设置物料名
        		jacContractItemImp.setItemname(itemname);
        		jacContractItemImp.setCreateuser(user);
        		jacContractItemImp.setCreateusername(username);
        		jacContractItemImp.setCreatedate(date);
        		jacContractItemImp.setCreatetime(time);
        		jacContractItemImp.setUnit("pcs");
    		if (StringUtils.isBlank(jacContractItemImp.getValiddate()) || "".equals(jacContractItemImp.getValiddate()))
    		{   
    		    String vailddate = jacContractMapper.selectValiDateBycode(jacContractItemImp.getContractcode()).toString();
    		    if (StringUtils.isBlank(vailddate) || vailddate == null)
    		    {	
    		    	return "新增物料失败！ " + jacContractItemImp.getContractcode() + "合同号不存在!";
    		    }
    		    jacContractItemImp.setValiddate(vailddate.substring(0, 4) 
    		    		+ "-" 
    		    		+ vailddate.substring(4, 6) 
    		    		+ "-" 
    		    		+ vailddate.substring(6, 8) + " 00:00:00");
    		}

    		int i = jacContractItemMapper.insertJacContractItem(jacContractItemImp);
    		  if (i != 1)
    		   {
    			  result = "物料：" + itemcode + "添加失败，请重新导入或联系管理员!";
    			  log.info(result);
    			  return result;
    		   }
    	  }
    	
		int i = jacContractMapper.updateAmount(contractcode);
		if (i != 1)
		{   
			result = "更新合同" + contractcode + "未税金额、合同金额失败，请联系管理员!";
			log.error(result);
			return result;
		}
		
        return result;
    }
    
    /**
     * 批量新增合同物料明细
     * 
     * @param datas 合同物料明细
     * @return 结果
     */
    @Override
    public String insertJacContractItems(Map<String,List<JacContractItem>> datas)
    {   
    	String result = "1";

    	//获取当前时间和当前用户名
    	/*String validdate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " 00:00:00";*/
    	Long date = Long.valueOf(new SimpleDateFormat("yyyyMMdd").format(new Date()));
    	String time = new SimpleDateFormat("HHmmss").format(new Date());
    	HttpServletRequest request = ServletUtils.getRequest();
        String user = request.getHeader(Constants.CURRENT_USERNAME);
        String username = jacContractMapper.selectUserNameById(request.getHeader(Constants.CURRENT_ID));
        //获取公司合同code和物料明细信息，批量新增物料
    	List<JacContractItem> jacContractItems = (List<JacContractItem>) datas.get("datas");
    	List<String> checkitems = new ArrayList<String>(); 
  	    String contractcode = null;
    	for (JacContractItem jacContractItem : jacContractItems)
    	{   
 		if (contractcode == null)
    		{   
    			contractcode = jacContractItem.getContractcode();
            	if (!"ContractNew".equals(jacContractMapper.checkStatus(contractcode)))
            	{
            		return "只允许新增状态合同新增物料！";
            	}
    		}
    		if (jacContractItemMapper.checkitem(jacContractItem.getItemcode(),jacContractItem.getContractcode()) > 0)
    		{
    			checkitems.add(jacContractItem.getItemcode());
    		}
    		else 
    		{   
    		    jacContractItem.setQuantity(0.0);
    		    jacContractItem.setTotalamount(0.0);
    		    jacContractItem.setPrice(0.0);
    		    jacContractItem.setLastyearprice(0.0);
    		    jacContractItem.setUntaxprice(0.0);
    		    jacContractItem.setRate(13.0);
    		    jacContractItem.setCreateuser(user);
    		    jacContractItem.setCreateusername(username);
    		    jacContractItem.setCreatedate(date);
    		    jacContractItem.setCreatetime(time);
    		    jacContractItem.setUnit("pcs");
    		    String vailddate = jacContractMapper.selectValiDateBycode(jacContractItem.getContractcode()).toString();
    		    if (StringUtils.isBlank(vailddate) || vailddate == null)
    		    {	
    		    	return "新增物料失败！ " + jacContractItem.getContractcode() + "合同号不存在!";
    		    }
    		    jacContractItem.setValiddate(vailddate.substring(0, 4) 
    		    		+ "-" 
    		    		+ vailddate.substring(4, 6) 
    		    		+ "-" 
    		    		+ vailddate.substring(6, 8) + " 00:00:00");
    		    try {
					jacContractItemMapper.insertJacContractItem(jacContractItem);
				} catch (Exception e) {
					result = "物料：" + jacContractItem.getItemcode() + "添加失败，请联系管理员处理";
	    			log.info(result);
	    			return result;
				}
    	  }
    	}
    	if (checkitems != null && checkitems.size() > 0)
    	{   
    		result = "新增的物料已在合同中存在，请勿重复添加！！已存在的物料为： "  + Joiner.on(",").join(checkitems);
    		log.info(result);
    		return result;
    	}
        return result;
    }

    /**
     * 批量修改合同物料明细
     * 
     * @param datas 合同物料明细
     * @return 结果
     */
    @Override
    public String updateJacContractItems(Map<String,Object> datas)
    {   
    	String result = "1";
    	HttpServletRequest request = ServletUtils.getRequest();
    	String user = request.getHeader(Constants.CURRENT_USERNAME);
    	String username = jacContractMapper.selectUserNameById(request.getHeader(Constants.CURRENT_ID));
    	String date = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    	
    	String contractcode = (String) datas.get("contractcode");
    	@SuppressWarnings("unchecked")
		List<Object> jacContractItems =  (List<Object>) datas.get("datas");

    	for (int i=0;i<jacContractItems.size();i++)
    	{   
    		Object obj = jacContractItems.get(i);
    		JSONObject json = (JSONObject) JSON.toJSON(obj);
    		JacContractItem jacContractItem = JSON.toJavaObject(json,JacContractItem.class);
    		//获取含税单价
    		Double price = getPrice(jacContractItem.getUntaxprice(),jacContractItem.getRate());
    		jacContractItem.setPrice(price);
    		//获取含税金额
    		jacContractItem.setTotalamount(getTotalamount(price,jacContractItem.getQuantity()));
    		jacContractItem.setLoguser(user);
    		jacContractItem.setLogusername(username);
    		jacContractItem.setLogdate(Long.valueOf(date.substring(0,8)));
    		jacContractItem.setLogtime(Long.valueOf(date.substring(8,14)));
    		try {
				jacContractItemMapper.updateJacContractItem(jacContractItem);
			} catch (Exception e) {
    			result = "更新合同" + contractcode + ":" +jacContractItem.getItemcode() + "失败！";
    			log.error(result);
    			return result;
			}
    	}
		int k = jacContractMapper.updateAmount(contractcode);
		if (k !=1)
		{   
			result = "更新合同" + contractcode + "未税金额、合同金额失败！";
			log.error(result);
			return result;
		}
        return result;
    }
    
    
    /**
     * 通过未税价格和税率获取含税单价
     * @param 未税价格、税率
     * @return 含税价格
     */
    public Double getPrice(Double untaxprice,Double rate)
    {
    	return untaxprice * ( 1 + rate/100);
    }
    
    /**
     * 通过含税单价和数量获取含税金额
     * @param 未税价格、税率
     * @return 含税价格
     */
    public Double getTotalamount(Double price,Double quantity)
    {
    	return price * quantity;
    }

    /**
     * 修改合同物料明细
     * 
     * @param jacContractItem 合同物料明细
     * @return 结果
     */
    @Override
    public int updateJacContractItem(JacContractItem jacContractItem)
    {   
    	
        return jacContractItemMapper.updateJacContractItem(jacContractItem);
    }

    /**
     * 删除合同物料明细对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public String deleteJacContractItemByIds(String ids)
    {   
    	String result = "1";
    	String[] id = ids.split(",");
    	for ( String itemid : id)
    	{   
    		
    		 try {
				jacContractItemMapper.deleteJacContractItemById(Long.valueOf(itemid));
			} catch (Exception e) {
				log.error("物料明细ID" + itemid + "删除失败，请联系管理员！",e);
				result = "物料明细ID" + itemid + "删除失败，请联系管理员！";
			}
        		
    	}
        return result;
    }

    /**
     * 删除合同物料明细信息
     * 
     * @param companycode 合同物料明细ID
     * @return 结果
     */
    public int deleteJacContractItemById(String companycode)
    {
        return jacContractItemMapper.deleteJacContractItemById(Long.valueOf(companycode));
    }
    
    /**
     * 定时更新价格走势表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @Scheduled(cron = "0 0/40 0 * * ?")
    public void insertContractPriceCron()
    {   
    	Date date = new Date();
    	log.info("定时更新价格走势表,作业已启动！",date);
    	if (redisTemplate.hasKey("contract_price_cron"))
    	{
    		log.info("合同价格趋势计算作业正在进行中，不能重复启动！");
    		return;
    	}
    	JacContractPrice contractPriceCron = new JacContractPrice();
    	contractPriceCron.setCreatedate(date);
    	contractPriceCron.setResult("开始");
    	jacContractItemMapper.insertContractPriceCron(contractPriceCron);
    	jacContractItemMapper.insertPrice();
    	redisTemplate.opsForValue().set("contract_price_cron",date,60,TimeUnit.MINUTES);	
    	List<JacContractPrice> newperices = jacContractItemMapper.selectNewPrice();
    	List<String> contractcodeList = newperices.stream().map(JacContractPrice::getContractcode).distinct().collect(Collectors.toList());
        log.info("打印合同号",contractcodeList);
    	if (newperices.size() == 0 || newperices == null)
        {
        	return;
        }
        for (JacContractPrice newperice: newperices)
        {   
        	newperice.setCreatedate(date);
        	newperice.setLogdate(date);
        	jacContractPriceMain.priceCronMain(newperice);
        	jacContractPriceMain.fillPrice(newperice);
        	jacContractPriceMain.fillUntaxPrice(newperice);
        	jacContractPriceMain.fillLastPrice(newperice);
        }
        for (String contractcode : contractcodeList)
        {   
        	JacContract jacContract = new JacContract();
        	jacContract.setAddition1(END);
        	jacContract.setContractcode(contractcode);
        	jacContractMapper.updateContractStatus(jacContract);
        }    
        redisTemplate.delete("contract_price_cron");
        contractPriceCron.setCreatedate(new Date());
        contractPriceCron.setResult("结束");
        jacContractItemMapper.insertContractPriceCron(contractPriceCron);
        log.info("定时更新价格走势表,作业已完成！");
    }
    
    /**
     * 查询价格趋势表
     * @param jacContractPriceList
     * @return
     */
    @Override
    public List<JacContractPriceList> selectContractPriceList(JacContractPriceList jacContractPriceList)
    {  
    	return jacContractItemMapper.selectContractPriceList(jacContractPriceList);
    }
    

}
